import { Color, Mesh, MeshRenderer, utils, Vec3, _decorator } from "cc";
import yyComponent from "../../Script/Common/yyComponent";

const { ccclass, property } = _decorator;
/**武器拖尾 */
@ccclass('Streak')
export default class Streak extends yyComponent {

    /***************************************通用流程***************************************/
    public init(data?) {
        this.initMesh();

        if (undefined !== data) {
            this.setData(data);
        }
    }
    protected setData(data: { color?: Color, soft?: number }) {
        if (undefined !== data.soft) {
            this.soft = data.soft;
        }
        if (undefined !== data.color) {
            this.color.set(data.color);
            let tr = 1 / 255;
            let r = data.color.r * tr;
            let g = data.color.g * tr;
            let b = data.color.b * tr;
            let a = data.color.a * tr;
            let index = 0;
            let count = this.level * 2;
            for (let i = 0; i < count; ++i) {
                this.meshData.colors[index++] = r;
                this.meshData.colors[index++] = g;
                this.meshData.colors[index++] = b;
                this.meshData.colors[index++] = a;
            }
            utils.createMesh(this.meshData, this.mesh);
            this.meshRender.mesh = this.mesh;
        }
    }

    /***************************************对外功能***************************************/
    /**
     * 开始播放拖尾特效
     * @param data 
     * @param data.topPos       剑尖世界坐标
     * @param data.bottomPos    剑柄世界坐标
     * @param data.color        拖尾颜色
     */
    public play(data: { topPos: Vec3, bottomPos: Vec3, color?: Color }) {
        this.topPos.set(data.topPos);
        this.bottomPos.set(data.bottomPos);
        let index = 0;
        for (let i = 0; i <= this.level; ++i) {
            this.topVerts[i].set(data.topPos);
            this.bottomVerts[i].set(data.bottomPos);
            this.meshData.positions[index++] = data.topPos.x;
            this.meshData.positions[index++] = data.topPos.y;
            this.meshData.positions[index++] = data.topPos.z;
            this.meshData.positions[index++] = data.bottomPos.x;
            this.meshData.positions[index++] = data.bottomPos.y;
            this.meshData.positions[index++] = data.bottomPos.z;
        }
        if (undefined !== data.color) {
            let tr = 1 / 255;
            let r = data.color.r * tr;
            let g = data.color.g * tr;
            let b = data.color.b * tr;
            let a = data.color.a * tr;
            let index = 0;
            let count = this.level * 2;
            for (let i = 0; i <= count; ++i) {
                this.meshData.colors[index++] = r;
                this.meshData.colors[index++] = g;
                this.meshData.colors[index++] = b;
                this.meshData.colors[index++] = a;
            }
        }
        utils.createMesh(this.meshData, this.mesh);
        this.meshRender.mesh = this.mesh;
    }
    /**
     * 拖尾头部移动到指定位置
     * @param topPos    剑尖世界坐标
     * @param bottomPos 剑柄世界坐标
     */
    public moveTo(topPos: Vec3, bottomPos: Vec3) {
        this.topPos.set(topPos);
        this.bottomPos.set(bottomPos);
    }

    /***************************************管理属性***************************************/
    //#region 网格数据
    protected meshRender: MeshRenderer = null;
    protected mesh: Mesh = null;
    /**网格顶点数据 */
    protected meshData: { positions: number[], uvs: number[], indices: number[], colors: number[] } = null;
    /**剑尖的顶点 */
    protected topVerts: Vec3[];
    /**剑柄处的顶点 */
    protected bottomVerts: Vec3[];
    /**拖尾颜色 */
    @property({
        type: Color,
        tooltip: "拖尾颜色",
    })
    protected color: Color = new Color();
    /**顶点细分等级 */
    @property({
        tooltip: "顶点细分等级，值越大拖尾越平滑"
    })
    protected level: number = 5;
    /**拖尾的柔软度，值越大尾巴越柔软 */
    @property({
        tooltip: "拖尾的柔软度，值越大尾巴越柔软，拉的越长"
    })
    protected soft: number = 5;
    /**剑尖坐标 */
    protected topPos: Vec3 = null;
    /**剑柄坐标 */
    protected bottomPos: Vec3 = null;
    protected initMesh() {
        this.meshRender = this.node.getComponent(MeshRenderer);

        this.topPos = new Vec3();
        this.bottomPos = new Vec3();

        this.meshData = {
            positions: [],
            uvs: [],
            indices: [],
            colors: [],
        };
        this.topVerts = [];
        this.bottomVerts = [];
        //顶点、UV、颜色
        let r = this.color.r;
        let g = this.color.g;
        let b = this.color.b;
        let a = this.color.a;
        let index = 0;
        for (let i = 0; i <= this.level; ++i) {
            this.topVerts.push(new Vec3());
            this.meshData.uvs.push(i / this.level, 0);

            this.bottomVerts.push(new Vec3());
            this.meshData.uvs.push(i / this.level, 1);

            this.meshData.positions.push(0, 0, 0, 0, 0, 0);

            this.meshData.colors[index++] = r;
            this.meshData.colors[index++] = g;
            this.meshData.colors[index++] = b;
            this.meshData.colors[index++] = a;
            this.meshData.colors[index++] = r;
            this.meshData.colors[index++] = g;
            this.meshData.colors[index++] = b;
            this.meshData.colors[index++] = a;
        }
        //三角面顶点索引
        for (let i = 0; i < this.level; ++i) {
            index = i * 2;
            this.meshData.indices.push(
                index, index + 1, index + 2,
                index + 2, index + 1, index + 3
            );
        }

        this.mesh = utils.createMesh(this.meshData);
        this.meshRender.mesh = this.mesh;
    }
    //#endregion

    /**根据当前顶点坐标更新网格顶点数据 */
    protected updateMesh(dt: number) {
        let dis = 0.05;
        for (let i = this.topVerts.length - 1; i >= 1; --i) {
            if (this.topVerts[i].z - this.topVerts[i - 1].z > dis) {
                this.topVerts[i].set(this.topVerts[i - 1]);
            }
            if (this.bottomVerts[i].z - this.bottomVerts[i - 1].z > dis) {
                this.bottomVerts[i].set(this.bottomVerts[i - 1]);
            }
        }
        //更新剑尖和剑柄的顶点坐标
        this.topVerts[0].set(this.topPos);
        this.bottomVerts[0].set(this.bottomPos);

        // //更新其余顶点坐标
        // let rate = this.soft == 0 ? 0.2 : (1 / this.soft);//根据柔软等级确定顶点偏移量
        // for (let i = 1; i <= this.level; ++i) {
        //     //剑尖端顶点
        //     let p1 = this.topVerts[i];
        //     let p2 = this.topVerts[i - 1];
        //     p1.x += (p2.x - p1.x) * rate;
        //     p1.y += (p2.y - p1.y) * rate;
        //     p1.z += (p2.z - p1.z) * rate;
        //     //剑柄端顶点
        //     p1 = this.bottomVerts[i];
        //     p2 = this.bottomVerts[i - 1];
        //     p1.x += (p2.x - p1.x) * rate;
        //     p1.y += (p2.y - p1.y) * rate;
        //     p1.z += (p2.z - p1.z) * rate;
        // }
        //将顶点坐标赋值给网格顶点数据
        let index = 0;
        for (let i = 0; i <= this.level; ++i) {
            this.meshData.positions[index++] = this.topVerts[i].x;
            this.meshData.positions[index++] = this.topVerts[i].y;
            this.meshData.positions[index++] = this.topVerts[i].z;

            this.meshData.positions[index++] = this.bottomVerts[i].x;
            this.meshData.positions[index++] = this.bottomVerts[i].y;
            this.meshData.positions[index++] = this.bottomVerts[i].z;
        }
        //更新网格
        utils.createMesh(this.meshData, this.mesh);
        this.meshRender.mesh = this.mesh;
    }

    update(dt) {
        this.updateMesh(dt);
    }
}
